// JORGE FERNANDO GOMEZ
// 1259371
// 189631
// LEC A1
// MARTIN MÜLLER
// D02
// YANG LIU


/* hash module.
 *
 * This is a simple hash module I implemented to
 * simplify the lander operations required, and because
 * I really liked using Perl dispatch tables via hashes
 * and subroutine references.  So I decided I should try
 * to replicate it in C.
 *
 * (If a TA happens to read this, I would appreciate any
 * tips or pointers of how to improve this module for
 * later use, or where I can read about it to improve it.)
 *
 * It supports simple hash operations like inserting,
 * searching, deleting.  I also added a few more like
 * hashRetrieve, which returns the exact node that was created
 * for a certain key, hashGetValue, which returns just the
 * satellite data stored for some key, and hashUpdate, which
 * is called by hashInsert if some key was already previously
 * stored, so the only thing to be updated is its satellite data.
 *
 * A hash table is created by calling newHashTable function with
 * given table size.  Colissions are resolved with chaining.
 * hashKey computes the h(k) value for some char * key and a
 * hash * Table.  It uses the multiplication method, and a string
 * is represnted as a number by taking each char in the string and
 * changing to base 13. */

#ifndef HASH_H
#define HASH_H 1

#define DEFAULT_SIZE 64

#include <stdbool.h>

/* node struct represents an object in the hash table.

   key      =>  indicates the object's hash key
   prev     =>  indicates the previous element on the linked list
                for that h(k) array slot.
   next     =>  indicates the next element on the linked list
                for that h(k) array slot.
   other    =>  * Placeholder */

struct node {
    void * key;
    void * data;

    struct node * prev;
    struct node * next;
};

/* Typedef to make code more readable. */
typedef struct node * hash_element;


/* A variable of type hash contains an array of linked lists
   which represent the hash table. */
typedef struct {
    hash_element * hashTable;
    int size;
} hash;



/* Struct to keep track of all the allocated hash tables. */
struct hashTables {
    hash * next;
};




/* Function prototypes */
/* See ./hash.c for more information. */


/*+*+*+*+*+*+*+*+*+*+*+*
 *   Hash operations   *
 *+*+*+*+*+*+*+*+*+*+*+*/

    /* Inserts an object to a hash table. */
    void hashInsert ( hash * Table, char * key, void * sat_data );

    /* Searches for a key in a hash table to see if it exists. */
    bool hashExists ( hash * Table, char * key );

    /* Retrieves the object from a key from a hash table. */
    hash_element hashRetrieve ( hash * Table, char * key );

    /* Retrieves the value stored from a key from a hash table. */
    void* hashGetValue ( hash * Table, char * key );

    /* Deletes an element from a hash table. */
    void hashDelete ( hash * Table, hash_element aNode );


/*+*+*+*+*+*+*+*+*+*+*+*
 *    Hash utilities   *
 *+*+*+*+*+*+*+*+*+*+*+*/

    /* Creates a new hash table of a given size. */
    //void newHashTable ( hash * table, int size );
    hash* newHashTable ( int size );

    /* Computes the hash value of key. */
    int hashKey ( hash * Table, char * key );

    /* Replaces the value stored at an existing key. */
    void hashUpdate( hash_element element, void * sat_data );

#endif /* end of include guard: HASH_H */
